libxl: Cope with pipes which signal POLLHUP|POLLIN on read eof
authorIan Jackson <ian.jackson@eu.citrix.com>
Tue, 7 Apr 2015 13:05:28 +0000 (14:05 +0100)
committerIan Campbell <ian.campbell@citrix.com>
Wed, 15 Apr 2015 12:57:50 +0000 (13:57 +0100)
commitda7e6b3108a72941e7bf35f48495c67975a257e4
treeff21971e9519a2dc51351002afef3a090fd09fb4
parentef8da0184ddb5b3dbf6dbf08c4c037bca8fcf738
libxl: Cope with pipes which signal POLLHUP|POLLIN on read eof

Some operating systems (including Linux and FreeBSD[1]) signal not
(only) POLLIN when a reading pipe reaches EOF, but POLLHUP (with or
without POLLIN).  This is permitted[2].  The implications are that in
the general case it is not possible to determine whether POLLHUP
indicates an error or simply eof without attempting a read.

Datacopiers mishandle this, because they always treat POLLHUP
exceptionally (either reporting it via callback_pollhup, or treating
it as an error).  datacopiers reading from pipes on such OSs can fail
(perhaps leaving some data unprocessed) rather than completing
successfully.

[1] http://www.greenend.org.uk/rjk/tech/poll.html
[2] http://pubs.opengroup.org/onlinepubs/9699919799/functions/poll.html

Distinguishing POLLHUP is needed for pty fds, but most callers in
libxl do not care about POLLHUP except as an error or eof condition.

So change the datacopier semantics so that if callback_pollhup is not
specified we treat POLLHUP almost like POLLIN.  The difference is that
if we get HUP from poll, but EWOULDBLOCK from read, we must signal an
error rather than attempting the read again.

This fixes the problem which 7e9ec50b0535 was aimed at.

Signed-off-by: Ian Jackson <Ian.Jackson@eu.citrix.com>
CC: Ian Campbell <ian.campbell@citrix.com>
CC: Andrew Cooper <andrew.cooper3@citrix.com>
CC: Roger Pau Monné <roger.pau@citrix.com>
CC: Ross Lagerwall <ross.lagerwall@citrix.com>
CC: Wei Liu <wei.liu2@citrix.com>
Acked-by: Wei Liu <wei.liu2@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
tools/libxl/libxl_aoutils.c
tools/libxl/libxl_internal.h